package compilers;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Ex1 {
    public static void main(String[] args) throws IOException {
        //指定关键字
        String[] KeyWords = {"int", "short", "long", "char", "class", "finally", "public"};
        Scanner scanner = new Scanner(System.in);
        //将文件的第一行生成字符串
        String string = scanner.nextLine();
        //限制字符串的最大值
        final int length = 100;
        //给要分析的数据创建一个字符型数组
        char[] chars = new char[length];
        //索引值
        int Index = 0, key = 0;
        //集合存储数据
        List mylist = new ArrayList();
        System.out.println("词法分析的结果如下：");
        do {
            String strs = null;
            char t = string.charAt(Index);
            mylist = Check(t, chars, KeyWords, string, Index, strs);
            if (mylist.size() == 0) {
                Index++;
                continue;
            }
            //规定List的第一个元素为Index，第二个元素为key
            Index = Integer.parseInt((String) mylist.get(0));
            key = Integer.parseInt((String) mylist.get(1));
            String words = (String) mylist.get(2);

            System.out.println("(" + words + " , \t" + key + ")");
        } while (key != 0);
    }

    /**
     * @param t
     * @param chars
     * @param KeyWords
     * @param string
     * @param Index
     * @param strs
     * @return
     */
    public static List Check(char t, char[] chars, String[] KeyWords,
                             String string, int Index, String strs) {
        int keyId = -1, find = 0;
        List mylist = new ArrayList();
        /*
         * 第一部分：扫描分类：关键字，数非关键字，数字，关系运算符
         */
        //判断下一个读入的字符是否为空格，若读取到空格则跳过，提取下一个字符进行判断
        while (t != ' ') {   //t是扫描到的临时字符
            //判断当前字符是字母或者数字和字母的组合
            if (t >= 'a' && t <= 'z') {
                // 当读取到不是大小写字母或者数字时候判断为一个单词读取完成
                while (t >= 'a' && t <= 'z' || t >= 'A' && t <= 'Z' || t >= '0' && t <= '9') {
                    chars[find++] = t;
                    strs += t + "";
                    t = string.charAt(++Index);//读取下一个
                }
                // 与读取出来的字符判断是否为关键字
                strs = strs.substring(4);
                //这里的i限制对应指定关键字的数组大小
                for (int i = 0; i < 7; i++) {
                    if (strs.equals(KeyWords[i])) {
                        keyId = i + 1;
                        mylist.add(Index + "");
                        mylist.add(keyId + "");
                        mylist.add(strs);
                        return mylist;
                    }
                }

                //若为非关键字就当作为标识符
                keyId = 10;
                mylist.add(Index + "");
                mylist.add(keyId + "");
                mylist.add(strs);
                return mylist;
            }
            //判断当前字符是否为数字
            else if (t >= '0' && t <= '9') {
                find = 0;
                String tTokens = null;
                // 对后面的字符进行判断是否为数字
                while (t >= '0' && t <= '9') {
                    chars[find++] = t;
                    tTokens += t;
                    t = string.charAt(++Index);
                }

                // 不是数字则返回种别码，结束当前方法
                keyId = 11;
                tTokens = tTokens.substring(4);
                mylist.add(Index + "");
                mylist.add(keyId + "");
                mylist.add(tTokens + "");
                return mylist;
            }
            find = 0;

            /*
             * 第二部分：扫描分类：关系运算符
             */
            //判断当前字符是否为其他关系运算符
            String token = null;
            switch (t) {
                case '>':
                    chars[find++] = t;
                    token += t;
                    if (string.charAt(++Index) == '=') {
                        keyId = 31;
                        chars[find++] = t;
                        token += string.charAt(Index++);
                    } else {
                        keyId = 30;
                    }
                    mylist.add(Index + "");
                    mylist.add(keyId + "");
                    token = token.substring(4);
                    mylist.add(token);
                    return mylist;

                case '<':
                    chars[find++] = t;
                    token += t;
                    if (string.charAt(++Index) == '=') {
                        chars[find++] = t;
                        keyId = 33;
                        token += string.charAt(Index++);
                    } else {
                        keyId = 32;
                    }
                    mylist.add(Index + "");
                    mylist.add(keyId + "");
                    token = token.substring(4);
                    mylist.add(token);
                    return mylist;

                case ':':
                    chars[find++] = t;
                    token += t;
                    if (string.charAt(++Index) == '=') {
                        keyId = 29;
                        chars[find++] = string.charAt(Index);
                        token += string.charAt(Index++);
                    } else {
                        keyId = 28;
                    }
                    mylist.add(Index + "");
                    mylist.add(keyId + "");
                    token = token.substring(4);
                    mylist.add(token);
                    return mylist;

                case '*':
                    keyId = 20;
                    break;

                case '/':
                    keyId = 21;
                    break;

                case '+':
                    keyId = 22;
                    break;

                case '-':
                    keyId = 23;
                    break;

                case '=':
                    keyId = 24;
                    break;

                case ';':
                    keyId = 25;
                    break;

                case '(':
                    keyId = 26;
                    break;

                case ')':
                    keyId = 27;
                    break;

                case '#':
                    keyId = 0;
                    break;

                default:
                    keyId = -1;
                    break;

            }
            chars[find++] = t;
            mylist.add(++Index + "");
            mylist.add(keyId + "");
            mylist.add(t + "");
            return mylist;
        }
        return mylist;
    }
}
